C 声明
之前一直不明白 C++ 中声明怎么读,受到 CSAPP 指引,阅读了 The C Programming Language 的对应章节,包括 5.12 和 A.8,不得不感叹这是一本好书,既有严格性,又有启发性,其实单 5.12 一章,用一段就解决了我的困惑
书中先给出了给出了一段代码,读取声明,返回其自然语言描述,并给出了几个例子:
char **argv
argv: pointer to char
int (*daytab)[13]
daytab: pointer to array[13] of int
int *daytab[13]
daytab: array[13] of pointer to int
void *comp()
comp: function returning pointer to void
void (*comp)()
comp: pointer to function returning void
char (*(*x())[])()
x: function returning pointer to array[] of pointer to function returning char
char (*(*x[3])())[5]
x: array[3] of pointer to function returning pointer to array[5] of char
不难发现其中的一致格式和简单性。进一步,书中紧接着递归定义了 dcl,提示了它的递归结构,如此便能知道自己应该如何递归解析一则声明。规则可以用一个句子概括:越核心的,越本质,我们认为标识符(变量)是最核心的,递归向外扩展,越靠近它的修饰符,越能反映它是什么,需要注意的是,这里的靠近指的是,尽可能右结合修饰符,再左结合。例如
char (*(*x())[])()
其中标识符是 x,试图向右结合,发现有修饰符 (),这表明 x 的本质是一个函数,那么问题只剩下,x 是返回什么类型的函数?于是可以通过左结合 * 回答这个问题: x 是返回指针的函数!那么问题只剩下这个指针指向什么类型?......
接下来,书上给出了程序的具体代码,有趣的是,递归时输出的顺序和英文的语序有关,在中文里,本质的在最后,而英文中,本质的在开始。
最后,附录 A.8 再次采用递归定义的方式,对更一般的情况进行了严格定义,并介绍了旧式函数指正和新式函数指针声明,区别是新式需要在括号内写入函数参数的类型。